#include <iostream>
#include <sstream>
#include <unistd.h>
#include "util.h"
#include "string.h"
#include "stdlib.h"
//#include "io.h"

using namespace std;
string replaceSpace(const string& input)
{
    string output;
    int begin = 0;
    int index = 0;
    for (index = 0; index < input.length(); ++index)
    {
        if (input[index] == ' ')
        {
            if (begin != index)
                output += input.substr(begin, index - begin);
            begin = index + 1;
        }
    }
    if (begin != index)
        output += input.substr(begin, index - begin);
    return output;
}

int GetPrivateProfileInt(const char* sectionName, const char* keyName, int defaultValue, const char* fileName)
{
    ifstream iFile(fileName);
    if (!iFile)
    {
        return defaultValue;
    }
    int value = defaultValue;
    string line;
    string section;
    while(getline(iFile, line))
    {
        line = replaceSpace(line);
        if (line != "" && line[0] == '[' && line[line.length() - 1] == ']')
        {
            section = line.substr(1, line.length() - 1);
        }
        string::size_type index = line.find("=");
        if (index != string::npos && section == sectionName && line.substr(0, index) == keyName)
        {
            value = atoi(line.substr(index + 1).c_str());
            break;
        }
    }
    iFile.close();
    return value;
}

void GetPrivateProfileString(const char* sectionName, const char* keyName, const char* defaultValue, char returnValue[], unsigned int length, const char* fileName)
{
    ifstream iFile(fileName);
    if (!iFile)
    {
        strncpy(returnValue, defaultValue, length);
        returnValue[length - 1] = '\0';
        return;
    }
    string line;
    string section;
    while(getline(iFile, line))
    {
        line = replaceSpace(line);
        if (line != "" && line[0] == '[' && line[line.length() - 1] == ']')
        {
            section = line.substr(1, line.length() - 2);
        }
        string::size_type index = line.find("=");
        if (index != string::npos && section == sectionName && line.substr(0, index) == keyName)
        {
            strncpy(returnValue, line.substr(index + 1).c_str(), length);
            returnValue[length - 1] = '\0';
            return;
        }
    }
    //not found
    strncpy(returnValue, defaultValue, length);
    returnValue[length - 1] = '\0';
    iFile.close();
}
bool WritePrivateProfileString(const char* sectionName, const char* keyName, const char* value, const char* fileName)
{
    bool ret = false;
    //section是null则直接返回false
    if(sectionName == NULL)
    {
        return ret;
    }
    string strSection("[");
    strSection += string(sectionName) + "]";
    string strKey(keyName);
    strKey += "=";
    //文件不存在，则创建，且直接写入
    if(access(fileName, 0) != 0)
    {
        ofstream oFile(fileName);
        if (!oFile)
        {
            cerr << "write file error: " << fileName << endl;
            return ret;
        }
        //如果key和value不是null，才写内容
        if (sectionName != NULL && keyName != NULL)
        {
           oFile << strSection << endl
                << strKey << value << endl;
        }
        oFile.close();
        ret = true;
        return ret;
    }

    ifstream iFile(fileName);
    if (!iFile)
    {
       ret = false;
       return ret;
    }
    //查找每一行是否包含section
    string line;
    bool flagFindSection = false;//是否找到了section
    ostringstream oss;
    while (getline(iFile, line))
    {
        if (line.find(strSection) == string::npos) //该行不包含section，直接写入流
        {
            oss << line << endl;
        }
        else  
        {
            flagFindSection = true; //查到section
            ret = true;
            bool isBreak = false;
            //key是null，则跳过该section,写入其余section
            if (keyName == NULL)
            {
                while (getline(iFile, line))
                {
                    if (line.find("[") != string::npos)
                    {
                        isBreak = true;
                        break;
                    }
                }
            
                if (isBreak) //写入其余section
                {
                    oss << line << endl;
                    while(getline(iFile, line))
                    {
                        oss << line << endl;
                    }
                }
                break;
            }
        
            oss << line << endl;//section写入流
            isBreak = false;
            while(getline(iFile, line))
            {
                if (line.find(strKey) == string::npos && line.find("[") == string::npos)
                    oss << line << endl;
                else
                {
                    isBreak = true;
                    break;
                }
            }
            if (!isBreak)//文件末尾，若value!=null则直接加上key
            {
                //直接加上
                if (value != NULL)
                {
                    oss << strKey << value << endl;
                }
            }
            else if(line.find("[") != string::npos)//查到下一个section，若value!=null则在下一个section前直接加上key
            {
                if(value != NULL)
                {
                    oss << strKey << value << endl;
                }
                oss << line << endl;
                while(getline(iFile, line)) //剩余行写入流中
                {
                    oss << line << endl;
                }
                break;
            }
            else if(line.find(strKey) != string::npos)//查到key，若value!=null则修改value
            {
                if (value != NULL)
                {
                    line = strKey + value;
                    oss << line << endl;
                }
                while(getline(iFile, line)) //剩余行写入流中
                {
                    oss << line << endl;
                }
                break;
            }
        }
    }
    if (!flagFindSection)//若未查到该section，且key和value！=null，写入section和key=value
    {
        if(keyName != NULL && value != NULL)
        {
            oss << strSection << endl;
            oss << strKey << value << endl;
        }
    }
    iFile.close();
    ofstream oFile(fileName);
    //写打开文件
    if (!oFile)
    {
       ret = false;
       return ret;
    }
    oFile << oss.str();//写入流到文件
    
    oFile.close();
    return ret;
}
